package com.nulldev.util.java.utils.color;

import java.awt.Color;

import com.nulldev.util.math.MathUtil;

public class ColorUtil {

	/**
	 * I have a little bit of an annoucement...
	 */
	public static final Color TRANSPARENT = new Color(0, 0, 0, 0);
	
	public static final Color LIGHT_BLUE = new Color(90, 228, 211);
	
	public static final Color GREEN = new Color(0, 128, 0);

	public static Color invertBAD(final Color color) {
		final int r = 255 - color.getRed();
		final int g = 255 - color.getBlue();
		final int b = 255 - color.getGreen();
		return new Color(r, g, b);
	}
	
	public static Color invertd(final Color color) {
		final int r = 255 - color.getRed();
		final int g = 255 - color.getBlue();
		final int b = 255 - color.getGreen();
		return lighten(new Color(r, g, b), 4);
	}
	
	public static Color split(final Color color) {
		final int lum = getLuminance(color.getRGB());
		if (lum <= 128) {
			return darken(color, 2);
		}else {
			return lighten(color, 2);
		}
	}
	
	public static int getLuminance(final int argb) {
	    final int lum= (   77  * ((argb>>16)&255) 
	               + 150 * ((argb>>8)&255) 
	               + 29  * ((argb)&255))>>8;
	    return lum;
	}
	
	public static Color invert(final Color color) {
		return new Color((0xFFFFFF - color.getRGB()) | 0xFF000000);
	}
	
    public static Color darken(final Color color, final double fraction) {
        int red = (int)Math.round(color.getRed() * (1.0 - fraction));
        int green = (int)Math.round(color.getGreen() * (1.0 - fraction));
        int blue = (int)Math.round(color.getBlue() * (1.0 - fraction));
        if (red < 0) {
            red = 0;
        }
        else if (red > 255) {
            red = 255;
        }
        if (green < 0) {
            green = 0;
        }
        else if (green > 255) {
            green = 255;
        }
        if (blue < 0) {
            blue = 0;
        }
        else if (blue > 255) {
            blue = 255;
        }
        final int alpha = color.getAlpha();
        return new Color(red, green, blue, alpha);
    }
    
    public static Color lighten(final Color color, final double fraction) {
        int red = (int)Math.round(color.getRed() * (1.0 + fraction));
        int green = (int)Math.round(color.getGreen() * (1.0 + fraction));
        int blue = (int)Math.round(color.getBlue() * (1.0 + fraction));
        if (red < 0) {
            red = 0;
        }
        else if (red > 255) {
            red = 255;
        }
        if (green < 0) {
            green = 0;
        }
        else if (green > 255) {
            green = 255;
        }
        if (blue < 0) {
            blue = 0;
        }
        else if (blue > 255) {
            blue = 255;
        }
        final int alpha = color.getAlpha();
        return new Color(red, green, blue, alpha);
    }

	public static String toHex(final Color color) {
		return MathUtil.toHex(color.getRGB());
	}

	public static Color randomColor() {
		return new Color(MathUtil.randInt(0, 255), MathUtil.randInt(0, 255), MathUtil.randInt(0, 255));
	}
	
	public static Color randomColor(final int alpha) {
		return new Color(MathUtil.randInt(0, 255), MathUtil.randInt(0, 255), MathUtil.randInt(0, 255),
				MathUtil.clamp(0, 255, alpha));
	}
	
	public static Color rainbow(final long offset, final float fade) {
        final float hue = (System.nanoTime() + offset) / 1.0E10f % 1.0f;
        final long color = Long.parseLong(Integer.toHexString(Integer.valueOf(Color.HSBtoRGB(hue, 1.0f, 1.0f))), 16);
        final Color c = new Color((int)color);
        return new Color(c.getRed() / 255.0f * fade, c.getGreen() / 255.0f * fade, c.getBlue() / 255.0f * fade, c.getAlpha() / 255.0f);
    }
	
	public static Color rainbow(final long offset, final float fade, final float off) {
        final float hue = (System.nanoTime() + offset) / 1.0E10f % 1.0f;
        final long color = Long.parseLong(Integer.toHexString(Integer.valueOf(Color.HSBtoRGB(hue, 1.0f, 1.0f))), 16);
        final Color c = new Color((int)color);
        return new Color(MathUtil.clamp(0, 255, (c.getRed() + off)) / 255.0f * fade,
        		MathUtil.clamp(0, 255, (c.getGreen() + off)) / 255.0f * fade,
        		MathUtil.clamp(0, 255, (c.getBlue() + off)) / 255.0f * fade, c.getAlpha() / 255.0f);
    }
}
